#include "DirectXFramework.h"

float DegToRad(float Degrees)
{
	return (Degrees*D3DX_PI)/180;
}

float RadToDeg(float Radians)
{
	return (Radians*180)/D3DX_PI;
}

CDirectXFramework::CDirectXFramework()
{
	Camera = new _Camera();
	SetupProjectionMatrix();
	ViewMat = D3DXMATRIX(1,0,0,0,
						 0,1,0,0,
						 0,0,1,0,
						 0,0,0,1);
	ProjMat = D3DXMATRIX(1,0,0,0,
						 0,1,0,0,
						 0,0,1,0,
						 0,0,0,1);
	BoundMouseX = 0;
	BoundMouseY = 0;

	Time = 0;
	Frames = 0;

	//TEST CODE
	tempRender = NULL;
	PlanetRender = NULL;
	PlayerStates = NULL;
	MenuSprite = NULL;
	BackgroundTex = NULL;
	CrossHairs = NULL;
	WindowRectangle = NULL;
	Camera = NULL;
	//END TEST CODE;
	m_Sound=0; //Sound
}

CDirectXFramework::CDirectXFramework(HINSTANCE hInstance, std::string winCaption, D3DDEVTYPE devType, DWORD requestedVP)
	: D3DApp(hInstance, winCaption, devType, requestedVP)
{
	//TEST CODE
	tempRender = NULL;
	PlanetRender = NULL;
	PlayerStates = NULL;
	MenuSprite = NULL;
	BackgroundTex = NULL;
	CrossHairs = NULL;
	WindowRectangle = NULL;
	Camera = NULL;
	//END TEST CODE;

	Time = 0;
	Frames = 0;

	//FOV = D3DX_PI * 0.25f;
	Angle = 60;
	FOV = DegToRad(Angle);
	GameState = MainMenu;
	LastStateSwitch = 9001;
	CurrentMenuChoice = 0;
	MenuSwitch = 1.f;

	MersEngine.seed(unsigned int(time(NULL)));

	//MENU ITEM LOADING HERE
	if(!LoadMenuItems())
	{
		ErrorMessage("There is a problem loading the menu items");
		return;
	}

	HRESULT hr;
	//Loading Crosshairs
	hr = D3DXCreateTextureFromFileA(gd3dDevice, "Textures/crosshair.png", &CrossHairs);
	if(hr != S_OK)
	{
		ErrorMessage("There was a problem loading texture 'crosshair.png'");
		return;
	}

	gd3dDevice->ShowCursor(false);
	Camera = new _Camera(D3DXVECTOR3(0, 5, -10), D3DXVECTOR3(0,0,0));
	LoadEffects();

	D3DXCreateFontA(gd3dDevice, 16, 8, FW_BOLD, 12, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
					DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &ScoreFont);

	//TEST CODE
#ifdef _DEBUG
	D3DXCreateFontA(gd3dDevice, 16, 8, FW_BOLD, 12, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
					DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &DebugFont);
	D3DXCreateSprite(gd3dDevice, &FontSprite);
#endif

	// END TEST CODE

	PlayerStates = gDInput->GetControllerStatePointer(0);

	D3DVERTEXELEMENT9 VertexElements[] = 
	{
		{0, 0,  D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
		{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
		{0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
		D3DDECL_END()
	};	
	HR(gd3dDevice->CreateVertexDeclaration(VertexElements, &Vertex::Decl));
	SetupProjectionMatrix();

	WindowRectangle = new RECT;

	HWND WindowHWND = this->getMainWnd();
	GetWindowRect(WindowHWND, WindowRectangle);
	WindowRectangle->right -= 36;
	WindowRectangle->bottom -= 36;

	float x = float(WindowRectangle->right - WindowRectangle->left), y = float(WindowRectangle->bottom - WindowRectangle->top);
}

CDirectXFramework::~CDirectXFramework()
{
	//delete temp;
	if(WindowRectangle)
		delete WindowRectangle;

	if(Camera)
		delete Camera;

	if(MenuChoices.size() > 0)
		for(UINT i = 0; i < MenuChoices.size(); ++i)
		{
			MenuChoices[i]->ActivatedTexture->Release();
			MenuChoices[i]->DeactivatedTexture->Release();
			delete MenuChoices[i];
		}
}

void CDirectXFramework::LoadEntities( void )
{
	Globals->Player->SetEffect(tempRender);
	GenerateWorld();
	Globals->CleanUpModelList();
}

bool CDirectXFramework::checkDeviceCaps( void )
{
	return true;
}

void CDirectXFramework::onLostDevice( void )
{
	tempRender->OnLostDevice();
}

void CDirectXFramework::onResetDevice( void )
{
	tempRender->OnResetDevice();
	PlanetRender->OnResetDevice();
}

void CDirectXFramework::updateScene( float dt )
{
	gDInput->poll();
	LastStateSwitch += dt;


	if((gDInput->keyDown(DIK_ESCAPE) || gDInput->ControllerState[0].Gamepad.wButtons & XINPUT_CONTROLLER_START) && LastStateSwitch >= 0.250f)
	{
		switch(GameState)
		{
		case MainMenu:
			GameState = Game;
			LastStateSwitch = 0;
			SetCursorPos(300,300);
			break;
		case Game:
			GameState = MainMenu;
			LastStateSwitch = 0;
			MenuChoices[CurrentMenuChoice]->IsSelected = false;
			CurrentMenuChoice = 0;
			MenuChoices[CurrentMenuChoice]->IsSelected = true;
			break;
		}
	}

	if(GameState == Game)
		GameUpdate(dt);

	if(GameState == MainMenu)
		MenuUpdate(dt);


}

void CDirectXFramework::drawScene( void )
{
	if(gd3dDevice)
	{
		gd3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, BLACK, 1.0f, 0);
		//gd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
		gd3dDevice->BeginScene();

		if(GameState == Game)
		{
			GameUpdate(0);
			GameRender();
		}

		if(GameState == MainMenu)
			MenuRender();

		HRESULT hr = gd3dDevice->EndScene();
		
		if(hr != S_OK)
			MessageBox( NULL, "There has been a problem!", NULL , MB_OK );

		hr = gd3dDevice->Present(0, 0, 0, 0);
	}
}

void CDirectXFramework::SetupCamera( void )
{
	//D3DXMATRIX tempRotation;
	D3DXMatrixRotationYawPitchRoll(&Camera->RotMat, Camera->Angles.x, Camera->Angles.y, Camera->Angles.z);
	D3DXVECTOR3 up(0.0f, 1.0f, 0.0f);
	//D3DXMatrixRotationYawPitchRoll(&tempRotation,Camera->Angles.x, Camera->Angles.y, Camera->Angles.z);
	D3DXVec3TransformCoord(&up, &up, &Camera->RotMat);
	D3DXVECTOR3 target = D3DXVECTOR3(0,0,1);
	D3DXVec3Normalize(&target, &target);
	D3DXVECTOR4 tempTarget;
	D3DXVec3Transform(&tempTarget, &target, &Camera->RotMat);
	target = D3DXVECTOR3(Camera->Position.x + tempTarget.x, Camera->Position.y + tempTarget.y, Camera->Position.z + tempTarget.z); 
	D3DXMatrixLookAtLH(&ViewMat, &D3DXVECTOR3(Camera->Position.x, Camera->Position.y, Camera->Position.z), &target, &up);
}

void CDirectXFramework::LoadEffects( void )
{
	//General Render Setup
	ID3DXBuffer *errors = NULL;
	HRESULT f;
	f = D3DXCreateEffectFromFile(gd3dDevice, "GeneralRender.fx", NULL, NULL, D3DXSHADER_DEBUG, 0, &tempRender, &errors);

	if(f != S_OK)
	{
		MessageBox(NULL,
			"There has been a problem loading the file: GeneralRender.fx",
			"D3DXCreateEffectFromFile",
			MB_ICONERROR);
		DebugBreak();
	}

	Technique = tempRender->GetTechniqueByName("General");
	WVPMat = tempRender->GetParameterByName(0, "gWVPMat");

	f = D3DXCreateEffectFromFile(gd3dDevice, "PlanetRender.fx", NULL, NULL, D3DXSHADER_DEBUG, 0, &PlanetRender, &errors);

	if(f != S_OK)
	{
		MessageBox(NULL,
			"There has been a problem loading the file: PlanetRender.fx",
			"D3DXCreateEffectFromFile",
			MB_ICONERROR);

		if(errors != NULL)
		{
			MessageBox(NULL,
				(char*)errors->GetBufferPointer(),
				"D3DXCreateEffectFromFile",
				MB_ICONERROR);
		}
		DebugBreak();
	}

	PlanetTechnique = PlanetRender->GetTechniqueByName("Main");
	PlanetWVPMat = PlanetRender->GetParameterByName(0, "gWVPMat");

}

void CDirectXFramework::SetupProjectionMatrix( void )
{
	float w = (float)md3dPP.BackBufferWidth;
	float h = (float)md3dPP.BackBufferHeight;
	D3DXMatrixPerspectiveFovLH(&ProjMat, FOV, w/h, 0.5f, 50000.0f);
}

void CDirectXFramework::GameUpdate( float dt )
{
#ifdef _DEBUG
	Throttle = 0;
#endif
	static bool ThirdPerson = false;
	static float LastSpawn = 10.f;
	static float LastCameraSwitch = 0;
	static float LastReload = 0.0f;
	static float ExplosionTime = 0.0f;
	static bool MissileExplode = true;

	if(Globals->Player->GetIsDying())
	{
		ThirdPerson = true;
	}
	else
		ThirdPerson = false;

	LastSpawn += dt;
	LastReload += dt;

	D3DXMATRIX RotationMat;
	Globals->Player->SetForwardThrottle(0);

	/*if(TempShip->GetIsWarping())
	{
		Camera->Angles.x += DegToRad(gDInput->mouseDX() * dt) * (MOUSESENSITIVITYX/6);
		Camera->Angles.y += DegToRad(gDInput->mouseDY() * dt) * (MOUSESENSITIVITYY/6);
	}
	else
	{
		Camera->Angles.x += DegToRad(gDInput->mouseDX() * dt) * MOUSESENSITIVITYX;
		Camera->Angles.y += DegToRad(gDInput->mouseDY() * dt) * MOUSESENSITIVITYY;
	}*/


	if(!Globals->Player->GetIsWarping())
	{
		Camera->Angles.x += DegToRad((gDInput->mouseDX() * dt) * MOUSESENSITIVITYX);
		Camera->Angles.y += DegToRad((gDInput->mouseDY() * dt) * MOUSESENSITIVITYY);
	}
	else
	{
		Camera->Angles.x += DegToRad((gDInput->mouseDX() * dt) * (MOUSESENSITIVITYX/4));
		Camera->Angles.y += DegToRad((gDInput->mouseDY() * dt) * (MOUSESENSITIVITYY/4));
	}

	LastCameraSwitch += dt;
	if(gDInput->keyDown(DIK_C) && LastCameraSwitch >= .250)
	{
		ThirdPerson = !ThirdPerson;
		LastCameraSwitch = 0;
	}

	if((gDInput->ControllerState[0].Gamepad.sThumbRX > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
		|| (gDInput->ControllerState[0].Gamepad.sThumbRX < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE))
	{
		//Camera->SetAnglesLocalCoord(D3DXVECTOR3(DegToRad(gDInput->ControllerState[0].Gamepad.sThumbRX * dt) /250.f,0,0));
		if(!Globals->Player->GetIsWarping())
			Camera->Angles.x += DegToRad(gDInput->ControllerState[0].Gamepad.sThumbRX * dt) /250.f;
		else
			Camera->Angles.x += DegToRad(gDInput->ControllerState[0].Gamepad.sThumbRX * dt) /750.f;
	}

	if((gDInput->ControllerState[0].Gamepad.sThumbRY > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
		|| (gDInput->ControllerState[0].Gamepad.sThumbRY < -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE))
	{
		//Camera->SetAnglesLocalCoord(D3DXVECTOR3(0,DegToRad(gDInput->ControllerState[0].Gamepad.sThumbRY * dt) /250.f,0));
		if(!Globals->Player->GetIsWarping())
			Camera->Angles.y -= DegToRad(gDInput->ControllerState[0].Gamepad.sThumbRY* dt) /250.f;
		else
			Camera->Angles.y -= DegToRad(gDInput->ControllerState[0].Gamepad.sThumbRY* dt) /750.f;
	}

	if(gDInput->keyDown(DIK_0))
	{
		Globals->Player->SetVelocity(D3DXVECTOR3(0,0,0));
	}

	if(gDInput->keyDown(DIK_W))
	{
		//PlaySound(TEXT("Sounds/engine_sound.WAV"),NULL,SND_FILENAME);
#ifdef _DEBUG
		Throttle = 100;
#endif
		Globals->Player->SetForwardThrottle(100);
	}

	if(gDInput->keyDown(DIK_S))
	{
		//PlaySound(TEXT("Sounds/engine_sound.WAV"),NULL,SND_FILENAME);
#ifdef _DEBUG
		Throttle = -100;
#endif
		Globals->Player->SetBackwardThrottle(100);
	}


	if((gDInput->ControllerState[0].Gamepad.sThumbLY >  XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE))
	{
		Globals->Player->SetForwardThrottle(short(((float)gDInput->ControllerState[0].Gamepad.sThumbLY/32767)*100));
#ifdef _DEBUG
		Throttle = short(((float)gDInput->ControllerState[0].Gamepad.sThumbLY/32767)*100);
#endif
	}

	if((gDInput->ControllerState[0].Gamepad.sThumbLY < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE))
	{
		Globals->Player->SetBackwardThrottle(short(((float)gDInput->ControllerState[0].Gamepad.sThumbLY/-32767)*100));
#ifdef _DEBUG
		Throttle = -short(((float)gDInput->ControllerState[0].Gamepad.sThumbLY/-32767)*100);
#endif
	}

	if(gDInput->keyDown(DIK_A)||(gDInput->ControllerState[0].Gamepad.sThumbLX < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE))
	{
	
	}
	if(gDInput->keyDown(DIK_D)||(gDInput->ControllerState[0].Gamepad.sThumbLX >  XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE))
	{
		
	}

	if(gDInput->keyDown(DIK_E) || (gDInput->ControllerState[0].Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER))
	{
		Globals->Player->ToggleWarp();
	}

	/*if(gDInput->keyDown(DIK_P) && (LastSpawn >=.25f))
	{
		AddBot();
		LastSpawn = 0;
	}

	/*if(gDInput->keyDown(DIK_O) && (LastSpawn >= .25f))
	{
		AddPlanet(UINT(dt*10000));
		LastSpawn = 0;
	}*/
	
	if((gDInput->keyDown(DIK_SPACE) || gDInput->mouseButtonDown(0) || (gDInput->ControllerState[0].Gamepad.bRightTrigger)) && !Globals->Player->GetIsWarping())
	{
		//PlaySound(TEXT("Sounds/missile_sound.WAV"),NULL,SND_FILENAME);  //lags and blows up after sound finishes playing twice
		Globals->Missile->ActivateMissile(dt);
	}

	if(Globals->Missile->GetIsExploded())
	{
		ExplosionTime += dt;
	}

	//if(gDInput->keyDown(DIK_R) && LastReload >= .125f)
	if(((gDInput->keyDown(DIK_R) || gDInput->mouseButtonDown(1) || (gDInput->ControllerState[0].Gamepad.bLeftTrigger)) && !Globals->Missile->GetIsExploded() && Globals->Missile->IsActive()) || (Globals->Missile->GetIsExploded() && MissileExplode))
	{
		CollisionSphere TempSphere;
		TempSphere.Radius = 800.f;
		TempSphere.Position = Globals->Missile->GetPosition();
		
		if(!Globals->Missile->GetIsExploded())
		{
			Globals->Missile->Explode();
			MissileExplode = false;
		}

		for(UINT i = 0; i < Globals->Bots.size(); ++i)
		{
			if(D3DXVec3LengthSq(&(Globals->Bots[i]->BotShip->GetPosition() - TempSphere.Position)) < TempSphere.Radius)
			{
				//Globals->Bots[i]->BotShip->SetPosition(Globals->Player->GetPosition() + D3DXVECTOR3(float(rand()%5000), float(rand()%5000), float(rand()%5000)));
				if(!Globals->Bots[i]->BotShip->GetIsDying())
				{
					++Score.PlayerScore;
				}
				Globals->Bots[i]->BotShip->KillMe();
			}
		}

		if(D3DXVec3LengthSq(&(Globals->Player->GetPosition() - TempSphere.Position)) < TempSphere.Radius)
		{
			if(!Globals->Player->GetIsDying())
			{
				--Score.PlayerScore;
			}

			Globals->Player->KillMe();
		}
	}

	if((Globals->Missile->GetIsExploded() && LastReload >=.125f  && ExplosionTime >= 5.f) && !Globals->Player->GetIsDying())
	{
		//PlaySound(TEXT("Sounds/reload_sound.WAV"),NULL,SND_FILENAME);  //sound plays twice
		//PlaySound(TEXT("Sounds/noise.WAV"),NULL,SND_FILENAME);
		Globals->Missile->SetPosition(Globals->Player->GetPosition());
		Globals->Missile->Reset();
		MissileExplode = true;
		Globals->Missile->Update(dt);
		//Globals->Missile->SetPosition(Globals->Player->GetPosition());
		ExplosionTime = 0;
		LastReload = 0;
	}

	for(UINT i = 0; i < Globals->Planets.size(); ++i)
	{
		if(CollisionTest::IsColliding(Globals->Planets[i]->MainSphere, Globals->Player->BoundingBox.BoundingBox))
		{
			Globals->Player->SetPosition((Globals->Player->GetPosition()) - (Globals->Player->GetVelocity()*(2*dt)));
			Globals->Player->SetVelocity(D3DXVECTOR3(0,0,0));
			if(!Globals->Player->GetIsDying())
			{
				--Score.PlayerScore;
			}

			Globals->Player->KillMe();
		}

		if(CollisionTest::IsColliding(Globals->Planets[i]->MainSphere, Globals->Missile->BoundingBox))
		{
			Globals->Missile->Explode();
			MissileExplode = false;
		}
	}

	for(UINT i = 0; i < Globals->Bots.size(); ++i)
	{
		Globals->Bots[i]->SetEyePosition(Camera->Position);

		for(UINT k = 0; k < Globals->Planets.size(); ++k)
		{
			if(CollisionTest::IsColliding(Globals->Planets[k]->MainSphere, Globals->Bots[i]->BotShip->BoundingBox.BoundingBox))
			{
				Globals->Bots[i]->BotShip->KillMe();
			}
		}

		if(CollisionTest::IsColliding(Globals->Missile, &Globals->Bots[i]->BotShip->BoundingBox))
		{
			if(!Globals->Player->GetIsDying())
			{
				CollisionSphere TempSphere;
				TempSphere.Radius = 800.f;
				TempSphere.Position = Globals->Missile->GetPosition();

				Globals->Missile->Explode();
				MissileExplode = false;
				//Globals->Bots[i]->BotShip->SetPosition(Globals->Player->GetPosition() + D3DXVECTOR3(float(rand()%5000), float(rand()%5000), float(rand()%5000)));
				if(!Globals->Bots[i]->BotShip->GetIsDying())
				{
					++Score.PlayerScore;
				}

				Globals->Bots[i]->BotShip->KillMe();


				if(D3DXVec3LengthSq(&(Globals->Player->GetPosition() - TempSphere.Position)) < TempSphere.Radius)
				{
					if(!Globals->Player->GetIsDying())
					{
						--Score.PlayerScore;
					}
					Globals->Player->KillMe();
				}
			}
		}
				
		if(CollisionTest::IsColliding(&Globals->Player->BoundingBox, &Globals->Bots[i]->BotShip->BoundingBox))
		{
			if(!Globals->Player->GetIsDying() && !Globals->Bots[i]->BotShip->GetIsDying())
			{
				/*Globals->Player->SetVelocity(D3DXVECTOR3(0,0,0));
				Globals->Bots[i]->BotShip->SetVelocity(-Globals->Bots[i]->BotShip->GetVelocity());*/
				if(!Globals->Player->GetIsDying())
				{
					++Score.PlayerScore;
				}

				if(!Globals->Bots[i]->BotShip->GetIsDying())
				{
					++Score.BotScore;
				}
				Globals->Player->KillMe();

				if(!Globals->Missile->IsActive() && !Globals->Missile->GetOldActive())
				{
					Globals->Missile->Explode();
					MissileExplode = false;
				}

				Globals->Bots[i]->BotShip->KillMe();
			}
		}

		if(Globals->Player->GetIsDying())
		{
			if(Globals->Bots[i]->GetBehaviorID() != 3)
			{
				Wander *NWander = new Wander(Globals->Bots[i], NULL);
				Globals->Bots[i]->ChangeState(NWander);
			}
		}

		else if(D3DXVec3LengthSq(&(Globals->Player->GetPosition() - Globals->Bots[i]->BotShip->GetPosition())) >= 500000.f && Globals->Bots[i]->GetBehaviorID() != 3)
		{
			Wander *NWander = new Wander(Globals->Bots[i], NULL);
			Globals->Bots[i]->ChangeState(NWander);
		}
		else if(D3DXVec3LengthSq(&(Globals->Player->GetPosition() - Globals->Bots[i]->BotShip->GetPosition())) < 500000.f && Globals->Bots[i]->GetBehaviorID() != 1)
		{
			Seek *NSeek = new Seek(Globals->Bots[i], Globals->Player);
			Globals->Bots[i]->ChangeState(NSeek);
		}
	}

	D3DXMATRIX RotMat;
	D3DXMatrixRotationYawPitchRoll(&RotMat, Camera->Angles.x, Camera->Angles.y, Camera->Angles.z);

	if(ThirdPerson)
	{
		D3DXMATRIX RotMat;
		D3DXMatrixRotationYawPitchRoll(&RotMat, Camera->Angles.x, Camera->Angles.y, Camera->Angles.z);
		D3DXVECTOR3 TempRot = D3DXVECTOR3(0, 0, -20);

		D3DXVec3TransformCoord(&TempRot, &TempRot, &RotMat); 

		Camera->Position = Globals->Player->GetPosition() + TempRot;
	}
	else
		Camera->Position = Globals->Player->GetPosition();// + D3DXVECTOR3(0, 2, -3);

	Globals->Player->SetAngles(Camera->Angles);

	if(Globals->Player->GetIsWarping())
	{
		static bool increase = false, stick = false;

		if(Angle > 122)
			stick = true;
		if(Angle < 58)
			stick = true;

		if(Globals->Player->GetEnterWarping())
		{
			increase = true;
			stick = false;
		}
		else if(Globals->Player->GetExitWarping())
		{
			increase = false;
			stick = false;
		}

		Camera->Angles.z = (DegToRad(float((rand()%2 - 1))));

		if(increase && !stick)
		{
			Angle += 45 * dt;
			//Camera->Angles.z += Camera->Angles.z * ((float(rand()&100))*dt);
		}
		else if(!increase && !stick)
		{
			Angle -= 30 * dt;
		}

	}
	else
	{
		if(Angle > 61 || Angle < 59)
		{
			Angle = Angle + ((60 - Angle)*dt);
		}
		else
			Angle = 60;

		if(Camera->Angles.z > (DegToRad(1)*dt) || Camera->Angles.z < (DegToRad(-1)*dt))
		{
			Camera->Angles.z = Camera->Angles.z + ((-Camera->Angles.z)*dt);
		}
		else
		{
			Camera->Angles.z = 0;
		}
	}

	if(Angle >= 125)
		Angle = 125;
	if(Angle <= 50)
		Angle = 50;


	Globals->Update(dt);

	FOV = DegToRad(Angle);
	SetupProjectionMatrix();

	SetupCamera();
	SetCursorPos(BoundMouseX,BoundMouseY);
	Time += dt;
}

void CDirectXFramework::GameRender( void )
{
	D3DXMATRIX TranslationMatrix, RotationMatrix,
			   ScaleMatrix, WVProjMatrix;
	static float FPS = 0;

	HRESULT hr = S_OK;
	
	if(Time >= 1.0f)
	{
		FPS = Frames / Time;
		Time = 0;
		Frames = 0;
	}

	hr = gd3dDevice->SetVertexDeclaration(Vertex::Decl);

	hr = tempRender->SetTechnique(Technique);

	WVProjMatrix = ViewMat * ProjMat;

	UINT passes = 0;
	UINT numPlanets = Globals->Planets.size();

	PlanetRenderList.clear();
	PlanetRenderList.shrink_to_fit();

	for(UINT k = 0; k < numPlanets; ++k)
	{
		if(D3DXVec3LengthSq(&(Camera->Position - Globals->Planets[k]->GetPosition())) < (60000000))
			PlanetRenderList.push_back(Globals->Planets[k]);
	}

#ifdef _DEBUG
	UINT NumPlanetsRenders = PlanetRenderList.size();
#endif

	PlanetRender->Begin(&passes, 0);
	for(UINT i = 0; i < passes; ++i)
	{
		PlanetRender->BeginPass(i);

		for(UINT j = 0; j < PlanetRenderList.size(); ++j)
		{
			D3DXMatrixRotationYawPitchRoll(&RotationMatrix, PlanetRenderList[j]->GetAngles().x,
															PlanetRenderList[j]->GetAngles().y,
															PlanetRenderList[j]->GetAngles().z);

			D3DXMatrixTranslation(&TranslationMatrix, PlanetRenderList[j]->GetPosition().x,
													  PlanetRenderList[j]->GetPosition().y,
													  PlanetRenderList[j]->GetPosition().z);

			D3DXMatrixScaling(&ScaleMatrix, PlanetRenderList[j]->GetScale().x,
											PlanetRenderList[j]->GetScale().y,
											PlanetRenderList[j]->GetScale().z);

			PlanetRender->SetMatrix(PlanetWVPMat, &(ScaleMatrix * RotationMatrix * TranslationMatrix * WVProjMatrix));
			PlanetRender->CommitChanges();
			PlanetRenderList[j]->Render();

			D3DXVECTOR3 debug = PlanetRenderList[j]->GetAngles();
			debug *= 0;
		}

		D3DXMatrixTranslation(&TranslationMatrix, Globals->SpaceBox->GetPosition().x,
												  Globals->SpaceBox->GetPosition().y,
												  Globals->SpaceBox->GetPosition().z);

		PlanetRender->SetMatrix(PlanetWVPMat, &(TranslationMatrix * WVProjMatrix));

		PlanetRender->CommitChanges();

		Globals->SpaceBox->Render();

		PlanetRender->EndPass();
	}
	PlanetRender->End();

	passes = 0;

	tempRender->Begin(&passes, 0);
	
	for(unsigned int i = 0; i < passes; ++i)
	{
		tempRender->BeginPass(i);
		D3DXMatrixTranslation(&TranslationMatrix, Globals->Player->GetPosition().x, Globals->Player->GetPosition().y, Globals->Player->GetPosition().z);
		tempRender->SetMatrix(WVPMat, &(TranslationMatrix * WVProjMatrix));
		tempRender->CommitChanges();

		for(UINT j = 0; j < Globals->Bots.size(); ++j)
		{
			Globals->Bots[j]->SetWVPMat(WVProjMatrix);
			Globals->Bots[j]->Render();
		}

		Globals->Player->SetEyePosition(Camera->Position);
		Globals->Player->SetWVPMat(WVProjMatrix);
		Globals->Player->Render();

		D3DXMatrixRotationYawPitchRoll(&RotationMatrix, Globals->Missile->GetAngles().x,
													    Globals->Missile->GetAngles().y,
														Globals->Missile->GetAngles().z);

		D3DXMatrixTranslation(&TranslationMatrix, Globals->Missile->GetPosition().x, Globals->Missile->GetPosition().y, Globals->Missile->GetPosition().z);
		Globals->Missile->SetWVPMatrix(WVProjMatrix);
		Globals->Missile->SetEyePosition(Camera->Position);
		tempRender->SetMatrix(WVPMat, &(RotationMatrix * TranslationMatrix * WVProjMatrix));
		tempRender->CommitChanges();
		Globals->Missile->Render();

		tempRender->EndPass();
	}

	tempRender->End();

#ifdef _DEBUG
	std::ostringstream ConvString;

	ConvString << "FPS: " << int(FPS) << "\nPlayer Position: " << Globals->Player->GetPosition().x << ", " << Globals->Player->GetPosition().y << ", " << Globals->Player->GetPosition().z;

	ConvString << "\nCamera Position: " << Camera->Position.x << ", " << Camera->Position.y << ", " << Camera->Position.z;
	ConvString << "\nCamera Angles: " << RadToDeg(Camera->Angles.x) << ", " << RadToDeg(Camera->Angles.y) << ", " << RadToDeg(Camera->Angles.z);
	
	ConvString << "\nNumber of Bots: " << Globals->Bots.size();
	ConvString << "\nNumber of Planets: " << Globals->Planets.size(); 
	ConvString << "\nPlayer Speed: " << D3DXVec3Length(&Globals->Player->GetVelocity());
	ConvString << "\nPlayer Throttle: " << Globals->Player->GetThrottle();
	ConvString << "\nDistance: " << D3DXVec3Length(&(Globals->Player->GetPosition()-Globals->Planets[0]->GetPosition())) << "\n";
	ConvString << "\nMissile Angles: " << Globals->Missile->GetAngles().x << ", " << Globals->Missile->GetAngles().y << ", " << Globals->Missile->GetAngles().z;
	ConvString << "\nFOV Angle: " << Angle;
	ConvString << "\nNumber of Planets Render: " << NumPlanetsRenders;

	RECT rect;
	rect.top = 25;
	rect.bottom = 900;
	rect.left = 25;
	rect.right = 1600;
	DebugFont->DrawTextA(NULL, ConvString.str().c_str(), -1, &rect, NULL, D3DXCOLOR(255,255,255,255));

	//DebugFont->DrawTextA(NULL, "\n_|_\n|", -1, &rect, DT_CENTER | DT_VCENTER, D3DXCOLOR(255,255,255,255));
	//bot->DebugOutput(DebugFont);*/
#endif
	RECT MainRect;

	MainRect.top = 25;
	MainRect.bottom = 900;
	MainRect.left = 25;
	MainRect.right = 1600;

	std::ostringstream OutputString;
	OutputString << "FPS: " << int(FPS)
		<< "\nPlayer Score: " << Score.PlayerScore
		<< "\nBot Score: " << Score.BotScore;
		//<< "\nNumber of Planets: " << Globals->Planets.size()
		//<< "\nNumber of PlanetsRendered: " << PlanetRenderList.size();
	MenuSprite->Begin(D3DXSPRITE_ALPHABLEND);
	ScoreFont->DrawTextA(MenuSprite, OutputString.str().c_str(), -1, &MainRect, NULL, D3DXCOLOR(255,255,255,255));
	if(!Globals->Player->GetIsDying())
	{
		MenuSprite->Draw(CrossHairs, NULL, &D3DXVECTOR3(25, 25, 0), &D3DXVECTOR3(WindowRectangle->right/2.f, WindowRectangle->bottom/2.f+13, 0), D3DXCOLOR(255,255,255,255));
	}

	MenuSprite->End();
	Frames++;
}

void CDirectXFramework::MenuUpdate( float dt )
{

	for(UINT i = 0; i < MenuChoices.size(); ++i)
	{
		MenuChoices[i]->Position = D3DXVECTOR3(WindowRectangle->right - (172.f * 3),
											  (WindowRectangle->bottom * 0.416f) + float(i*WindowRectangle->bottom * .1157f),
											   0);
	}

	MenuSwitch += dt;
	if((gDInput->keyDown(DIK_W) || gDInput->keyDown(DIK_UP) || (gDInput->ControllerState[0].Gamepad.sThumbLY > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) || (gDInput->ControllerState[0].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)) && MenuSwitch >= .2f)
	{
		MenuChoices[CurrentMenuChoice]->IsSelected = false;
		CurrentMenuChoice++;
		if(CurrentMenuChoice > MenuChoices.size() - 1)
			CurrentMenuChoice = 0;

		MenuChoices[CurrentMenuChoice]->IsSelected = true;
		MenuSwitch = 0;
		//PlaySound(TEXT("Sounds/menu_sound.WAV"),NULL,SND_FILENAME);
	}

	if((gDInput->keyDown(DIK_S) || gDInput->keyDown(DIK_DOWN) || (gDInput->ControllerState[0].Gamepad.sThumbLY < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) || (gDInput->ControllerState[0].Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)) && MenuSwitch >= .2f)
	{
		MenuChoices[CurrentMenuChoice]->IsSelected = false;
		CurrentMenuChoice--;
		if(CurrentMenuChoice > MenuChoices.size() - 1)
			CurrentMenuChoice = MenuChoices.size() - 1;

		MenuChoices[CurrentMenuChoice]->IsSelected = true;
		MenuSwitch = 0;
		//PlaySound(TEXT("Sounds/menu_sound.WAV"),NULL,SND_FILENAME);
	}

	if(gDInput->keyDown(DIK_RETURN) || (gDInput->ControllerState[0].Gamepad.wButtons & XINPUT_GAMEPAD_A) || (gDInput->keyDown(DIK_NUMPADENTER)))
	{
		switch( CurrentMenuChoice )
		{
		case 0:
			GameState = Game;
			//PlaySound(TEXT("Sounds/menu_start.WAV"),NULL,SND_FILENAME);
			LastStateSwitch = 0;
			SetCursorPos(BoundMouseX,BoundMouseY);
			break;

		case 1:
			//PlaySound(TEXT("Sounds/menu_exit.WAV"),NULL,SND_FILENAME);
			DestroyWindow(mhMainWnd);
			break;

		default:
			break;
		}
	}
}

bool CDirectXFramework::LoadMenuItems( void )
{	
	_MenuItem *TempMenuItem = new _MenuItem;

	HRESULT hr = S_OK;
	hr = D3DXCreateTextureFromFileA(gd3dDevice, "Textures/resumeGameActivated.png", &TempMenuItem->ActivatedTexture);
	if(hr != S_OK)
	{
		delete TempMenuItem;
		ErrorMessage("There was a problem loading texture 'resumeGameActivated.png'");
		return false;
	}

	hr = D3DXCreateTextureFromFileA(gd3dDevice, "Textures/resumeGameDeactivated.png", &TempMenuItem->DeactivatedTexture);
	if(hr != S_OK)
	{
		delete TempMenuItem;
		ErrorMessage("There was a problem loading texture 'resumeGameDeactivated.png'");
		return false;
	}

	TempMenuItem->IsSelected = true;
	TempMenuItem->Position = D3DXVECTOR3(200, 400, 0);
	MenuChoices.push_back(TempMenuItem);

	TempMenuItem = new _MenuItem;

	hr = D3DXCreateTextureFromFileA(gd3dDevice, "Textures/quitActivated.png", &TempMenuItem->ActivatedTexture);
	if(hr != S_OK)
	{
		delete TempMenuItem;
		ErrorMessage("There was a problem loading texture 'quitActivated.png'");
		return false;
	}

	hr = D3DXCreateTextureFromFileA(gd3dDevice, "Textures/quitDeactivated.png", &TempMenuItem->DeactivatedTexture);
	if(hr != S_OK)
	{
		delete TempMenuItem;
		ErrorMessage("There was a problem loading texture 'quitDeactivated.png'");
		return false;
	}

	TempMenuItem->IsSelected = false;
	TempMenuItem->Position = D3DXVECTOR3(200, 800, 0);
	MenuChoices.push_back(TempMenuItem);

	//Load Menu Background Here
	D3DXCreateSprite(gd3dDevice, &MenuSprite);
	hr = D3DXCreateTextureFromFileA(gd3dDevice, "Textures/TitleCard.png", &BackgroundTex);
	if(hr != S_OK)
	{
		ErrorMessage("There was a problem loading texture 'TitleCard.png'");
		return false;
	}
	return true;
}

void CDirectXFramework::MenuRender( void )
{
#ifdef _DEBUG
	DebugFont->DrawTextA(NULL, "MAIN MENU", -1, WindowRectangle, DT_CENTER | DT_VCENTER, D3DXCOLOR(255,255,255,255));
#endif
	MenuSprite->Begin(D3DXSPRITE_ALPHABLEND);
	D3DXMATRIX ScaleMat;

	HWND WindowHWND = GetDesktopWindow();
	GetWindowRect(WindowHWND, WindowRectangle);
	BoundMouseX = WindowRectangle->right/2;
	BoundMouseY = WindowRectangle->bottom/2;
	//WindowRectangle->right -= 36;
	//WindowRectangle->bottom -= 36;

	//float x = float(WindowRectangle->right - WindowRectangle->left), y = float(WindowRectangle->bottom - WindowRectangle->top);


	//D3DXVECTOR3 temp(float(WindowRectangle->right - WindowRectangle->left) / 1936.f, float(WindowRectangle->bottom - WindowRectangle->top) / 1118.f, 1.f);
	//D3DXVECTOR3 temp2(float(WindowRectangle->right - WindowRectangle->left), float(WindowRectangle->bottom - WindowRectangle->top), 0);
	D3DXMatrixScaling(&ScaleMat, float(WindowRectangle->right - WindowRectangle->left) / 1920.f, float(WindowRectangle->bottom - WindowRectangle->top) / 1080.f, 1.f);
	MenuSprite->SetTransform(&ScaleMat);

	MenuSprite->Draw(BackgroundTex, NULL, &D3DXVECTOR3(0, 0, 0), &D3DXVECTOR3(0,0,0), D3DXCOLOR(255,255,255,255));

	D3DXMatrixIdentity(&ScaleMat);
	MenuSprite->SetTransform(&ScaleMat);

	for(UINT i = 0; i < MenuChoices.size(); ++i)
	{
		if(MenuChoices[i]->IsSelected)
			MenuSprite->Draw(MenuChoices[i]->ActivatedTexture, NULL, &D3DXVECTOR3(0,0,0), &MenuChoices[i]->Position, D3DXCOLOR(255,255,255,255));
	
		else
			 MenuSprite->Draw(MenuChoices[i]->DeactivatedTexture, NULL, &D3DXVECTOR3(0,0,0), &MenuChoices[i]->Position, D3DXCOLOR(255,255,255,255));
	}
	
	MenuSprite->End();
}

void CDirectXFramework::ErrorMessage(std::string ErrorMessage)
{
	MessageBoxA(NULL, ErrorMessage.c_str(), "Fatal Error:", 0);
	DestroyWindow(mhMainWnd);
	if(gd3dDevice)
	{
		gd3dDevice->Release();
		gd3dDevice = NULL;
	}
	FatalError = true;
}

bool CDirectXFramework::InitializeSound()
{
	bool result;
	m_Sound = new SoundClass;
	if(!m_Sound)
	{
		return false;
	}
	result = m_Sound->Initialize(m_hwnd);
	if(!result)
	{
		MessageBox(m_hwnd,TEXT("Could not initialize Direct Sound."),TEXT("Error"),MB_OK);
		return false;
	}
	return true;
}

void CDirectXFramework::ShutdownSound()
{
	if(m_Sound)
		m_Sound->Shutdown();
	delete m_Sound;
	m_Sound = 0;
}

bool CDirectXFramework::AddPlanet( UINT seed )
{

	srand(seed);
	//CreateAsteroidField(D3DXVECTOR3(0,0,0), 1000);

	std::string FileName = "Models/";
	D3DXVECTOR3 Scale;
	int RandomNumber = 0;
	float Radius = 0;
	D3DXVECTOR3 Position, Rotation, Angles;

	//srand(UINT(time(NULL)));
	Angles = D3DXVECTOR3(0,0,0);

	RandomNumber =  rand() % 3;

	switch(RandomNumber)
	{
	case 0:
		Rotation.x = DegToRad(float(rand()%30 + 1));
		Rotation.y = 0;
		Rotation.z = 0;
		break;

	case 1:
		Rotation.y = DegToRad(float(rand()%30 + 1));
		Rotation.x = 0;
		Rotation.z = 0;
		break;

	case 2:
		Rotation.z = DegToRad(float(rand()%30 + 1));
		Rotation.y = 0;
		Rotation.x = 0;
		break;

	default:
		break;
	};

///	Random->MersEngine.seed(seed);

	/*RandomNumber =  rand() % 2;

	if(RandomNumber == 0)
		Position.x = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)) * Random->DoubleGenerator(Random->MersEngine)) * 100;
	else
		Position.x = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)) * Random->DoubleGenerator(Random->MersEngine)) * 100;

	RandomNumber =  rand() % 2;

	if(RandomNumber == 0)
		Position.y = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)) * Random->DoubleGenerator(Random->MersEngine)) * 100;
	else
		Position.y = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)) * Random->DoubleGenerator(Random->MersEngine)) * 100;

	RandomNumber =  rand() % 2;

	if(RandomNumber == 0)
		Position.z = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)) * Random->DoubleGenerator(Random->MersEngine)) * 100;
	else
		Position.z = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)) * Random->DoubleGenerator(Random->MersEngine)) * 100;
		*/

	RandomNumber = rand()%1000;
	if(RandomNumber >= 500)
		Position.x = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 + 400;
	else
		Position.x = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 - 400;

	RandomNumber = rand()%1000;
	if(RandomNumber >= 500)
		Position.y = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 + 400;
	else
		Position.y = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 - 400;

	RandomNumber = rand()%1000;
	if(RandomNumber >= 500)
		Position.z = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 + 400;
	else
		Position.z = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 - 400;

	//DEBUG CODE
	/*Position = D3DXVECTOR3(0,0,9);
	RandomNumber = 0;

	FileName = "Models/debris_wing.x";
	Scale = D3DXVECTOR3(3.f, 3.f, 3.f);
	Rotation = D3DXVECTOR3(0,0,0);
	Radius = 2.0f;*/


	RandomNumber = rand() % 12000;
	//RandomNumber = 11500;
	//Position *= 0;
	//Scale = D3DXVECTOR3(3.f,3.f,3.f);
	//RandomNumber = 5;
	
	if(RandomNumber < 1000)
		CreateAsteroidField(Position, (rand()%1000)+100, seed);

	else if(RandomNumber < 2000)
		CreateDebrisField(Position, (rand()%1000)+100, seed);

	else if(RandomNumber < 3000)
	{
		FileName += "Green_Blue_Planet.X";
		Scale = D3DXVECTOR3(3.0f, 3.0f, 3.0f);
		Radius = 31.f;
	}

	else if(RandomNumber < 4000)
	{
		FileName += "Greenish_Planet.X";
		Scale = D3DXVECTOR3(6.0f, 6.0f, 6.0f);
		Radius = 80.f;
	}

	else if(RandomNumber < 5000)
	{
		FileName += "Grey_Crater_Planet.X";
		Scale = D3DXVECTOR3(0.8f, 0.8f, 0.81f);
		Radius = 12.f;
	}

	else if(RandomNumber < 6000)
	{
		FileName += "Purple_Planet.x";
		Scale = D3DXVECTOR3(15.f, 15.f, 15.f);
		Radius = 267.f;
	}

	else if(RandomNumber < 7000)
	{
		FileName += "Ringed_Planet.x";
		Scale = D3DXVECTOR3(25.f, 25.f, 25.f);
		Rotation = D3DXVECTOR3(0.0f, 0.0f, DegToRad(float(rand()%60) - 30));
		Angles = D3DXVECTOR3(DegToRad(float(rand() % 721)-360),
			DegToRad(float(rand() % 721)-360),
			DegToRad(float(rand() % 721)-360));
		Radius = 169.f;	
	}

	else if(RandomNumber < 8000)
	{
		FileName += "copper_gas_planet.x";
		Scale = D3DXVECTOR3(4.f,4.f,4.f);
		Radius = 35.f;
	}

	else if(RandomNumber < 9000)
	{
		FileName += "cross_ring_planet.x";
		Scale = D3DXVECTOR3(14.f, 14.f, 14.f);
		Radius = 217.f; 
	}

	else if(RandomNumber < 10000)
	{
		FileName += "Ring_Planet_Purple.x";
		Scale = D3DXVECTOR3(25.f,25.f,25.f);
		Radius = 379.f;
	}

	else if(RandomNumber < 11000)
	{
		FileName += "stagger_ring_planet.x";
		Rotation = D3DXVECTOR3(0.0f, 0.0f, DegToRad(float(rand()%60) - 30));
		Angles = D3DXVECTOR3(DegToRad(float(rand() % 721)-360),
			DegToRad(float(rand() % 721)-360),
			DegToRad(float(rand() % 721)-360));
		Radius = 92.f;	
		Scale = D3DXVECTOR3(6.f,6.f,6.f);
	}

	else
	{
		FileName += "three_ring_planet.x";

		Rotation = D3DXVECTOR3(0.0f, 0.0f, DegToRad(float(rand()%60) - 30));
		Angles = D3DXVECTOR3(DegToRad(float(rand() % 721)-360),
			DegToRad(float(rand() % 721)-360),
			DegToRad(float(rand() % 721)-360));
		Radius = 92.f;	
		Scale = D3DXVECTOR3(6.f,6.f,6.f);

		//Scale = D3DXVECTOR3(15.f, 15.f, 15.f);
		//Radius = 267.f;
	}

	if(RandomNumber > 2000)
	{
		Planet *NPlanet = NULL;
		bool IsColliding = false;

		NPlanet = new Planet(gd3dDevice, Position, Scale, Rotation);
		NPlanet->SetPosition(Position);
		NPlanet->SetAngles(Angles);

		NPlanet->LoadXFile(FileName, 0);
		NPlanet->MainSphere.Radius = Radius;
		NPlanet->MainSphere.Position = NPlanet->GetPosition();

		for(UINT k = 0; k < Globals->Planets.size(); ++k)
		{
			if(Globals->CheckSpawnCollision(NPlanet, Globals->Planets[k]))
			{
				RandomNumber = rand()%1000;
				if(RandomNumber >= 500)
					Position.x = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 + 400;
				else
					Position.x = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 - 400;

				RandomNumber = rand()%1000;
				if(RandomNumber >= 500)
					Position.y = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 + 400;
				else
					Position.y = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 - 400;

				RandomNumber = rand()%1000;
				if(RandomNumber >= 500)
					Position.z = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 + 400;
				else
					Position.z = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% 7000) * Random->DoubleGenerator(Random->MersEngine)) * 100 - 400;
				NPlanet->SetPosition(Position);

				k = 0;
			}
		}


		Globals->Planets.push_back(NPlanet);

	}
	return true;
}

bool CDirectXFramework::AddBot( void )
{
	Wander *NSeek = NULL;
	Bot *NBot = NULL;

	NBot = new Bot(gd3dDevice, 200, NULL, D3DXVECTOR3(1.f,1.f,1.f), 200);
	NSeek = new Wander(NBot, Globals->Player);
	NBot->ChangeState(NSeek);
	NBot->SetEffect(tempRender);
	float t = float(Random->DoubleGenerator(MersEngine)*10000)-5000.f;

	//srand(UINT(time(NULL)));

	NBot->BotShip->SetPosition(GetRandomPosition(2048) + GetRandomPosition(2048));

	NBot->Update(0);
	int Size = Globals->Bots.size();
	for(int i = 0; i < Size; i++)
	{
		NBot->Update(0);
		if(CollisionTest::IsColliding(NBot->BotShip->BoundingBox.BoundingBox, Globals->Bots[i]->BotShip->BoundingBox.BoundingBox))
		{
			NBot->BotShip->SetPosition(GetRandomPosition(2048));
			i = -1;
		}
	}
	Globals->Bots.push_back(NBot);
	return false;
}

void CDirectXFramework::GenerateWorld()
{
	unsigned long NumberSeed = 0;
	for(UINT p = 0; p < 40; ++p)
	{
		NumberSeed = UINT(clock()*(p+1));
		AddPlanet(NumberSeed);
		Random->MersEngine.seed(NumberSeed);
	}

	for(UINT i = 0; i < 10; ++i)
		AddBot();

	Globals->Player->Update(0);
	for(UINT k = 0; k < Globals->Bots.size(); ++k)
		Globals->Bots[k]->Update(0);
}

void CDirectXFramework::CreateAsteroidField( D3DXVECTOR3 Position, UINT radius, UINT Seed )
{
	Planet *TempAsteroid = NULL;
	UINT NumAsteroids = NULL;
	D3DXVECTOR3 TempPosition = D3DXVECTOR3(0,0,0),
				Rotation = D3DXVECTOR3(0,0,0);
	UINT RandomNumber = 0;
	std::string FileName = "Models/";

	NumAsteroids = (Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine))+50;

	srand(Seed);

	for(UINT i = 0; i < NumAsteroids; ++i)
	{
		FileName = "Models/";

		RandomNumber = rand() % 8000;

		if(RandomNumber < 1000)
			FileName += "asteroid_01.X";

		else if(RandomNumber < 2000)
			FileName += "asteroid_02.X";

		else if(RandomNumber < 3000)
			FileName += "asteroid_03.X";

		else if(RandomNumber < 4000)
			FileName += "asteroid_04.X";

		else if(RandomNumber < 5000)
			FileName += "asteroid_05.X";

		else if(RandomNumber < 6000)
			FileName += "asteroid_06.X";

		else
			FileName += "asteroid_07.X";

		Rotation = GetAPlanetaryRotation();

		TempPosition = GetRandomPosition(radius);
		TempAsteroid = new Planet(gd3dDevice, (TempPosition + Position), D3DXVECTOR3(.4f, .4f, .4f), Rotation);
		TempAsteroid->MainSphere.Position = TempAsteroid->GetPosition();
		TempAsteroid->MainSphere.Radius = 8.f;

		TempAsteroid->LoadXFile(FileName, NULL);

		for(UINT k = 0; k < Globals->Planets.size(); ++k)
		{
			if(Globals->CheckSpawnCollision(TempAsteroid, Globals->Planets[k]))
			{
				TempPosition = GetRandomPosition(radius);
				TempAsteroid->SetPosition(Position + TempPosition);

				k = 0;
			}

		}

		Globals->Planets.push_back(TempAsteroid);
	}

	RandomNumber = rand()% 1000;

	if(RandomNumber < 100)
	{
		Globals->Planets[Globals->Planets.size()-1]->SetAngularVelocity(D3DXVECTOR3(0,0,DegToRad(2)));

		TempAsteroid = new Planet(gd3dDevice, Position + TempPosition + D3DXVECTOR3(0,0,1), D3DXVECTOR3(.15f, .15f, .15f), D3DXVECTOR3(0.f, 0.f, DegToRad(2)));
		TempAsteroid->MainSphere.Position = TempAsteroid->GetPosition();
		TempAsteroid->MainSphere.Radius = 1.f;

		TempAsteroid->LoadXFile("Models/debris_rocket_top.x", NULL);
		Globals->Planets.push_back(TempAsteroid);

		TempAsteroid = new Planet(gd3dDevice, Position + TempPosition + D3DXVECTOR3(0,0,2), D3DXVECTOR3(.15f, .15f, .15f), D3DXVECTOR3(0.f, 0.f, DegToRad(-2)));
		TempAsteroid->MainSphere.Position = TempAsteroid->GetPosition();
		TempAsteroid->MainSphere.Radius = 1.f;

		TempAsteroid->LoadXFile("Models/debris_rocket_mid.x", NULL);
		Globals->Planets.push_back(TempAsteroid);

		TempAsteroid = new Planet(gd3dDevice, Position + TempPosition + D3DXVECTOR3(0,0,3), D3DXVECTOR3(.15f, .15f, .15f), D3DXVECTOR3(0.f, DegToRad(2), 0.f));
		TempAsteroid->MainSphere.Position = TempAsteroid->GetPosition();
		TempAsteroid->MainSphere.Radius = 1.f;
		TempAsteroid->SetAngles(D3DXVECTOR3(0, DegToRad(180), 0));

		TempAsteroid->LoadXFile("Models/debris_rocket_end.x", NULL);
		Globals->Planets.push_back(TempAsteroid);
	}
	
}

void CDirectXFramework::CreateDebrisField( D3DXVECTOR3 Position, UINT radius, UINT Seed)
{
	Planet *Debris = NULL;
	UINT NumDebris = NULL;
	D3DXVECTOR3 TempPosition = D3DXVECTOR3(0,0,0),
				Scale = D3DXVECTOR3(1.f,1.f,1.f),
				Rotation = D3DXVECTOR3(0,0,0);
	UINT RandomNumber = 0;
	std::string FileName = "Models/";
	float CollisionRadius = 0;

	NumDebris = ((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)) % 30) + 20;

	Rotation = GetRandomDebrisRotation();

	for(UINT i = 0; i < NumDebris; ++i)
	{
		FileName = "Models/";
		RandomNumber = rand() % 14000;

		if(RandomNumber < 1000)
		{
			FileName += "debris_crate_p02.x";
			Scale = D3DXVECTOR3(0.3f, 0.3f, 0.3f);
			CollisionRadius = 1.5f;
		}


		else if(RandomNumber < 2000)
		{
			FileName += "debris_crate_p03.x";
			Scale = D3DXVECTOR3(0.3f, 0.3f, 0.3f);
			CollisionRadius = 1.5f;
		}

		else if(RandomNumber < 3000)
		{
			FileName += "debris_glass.x";
			CollisionRadius = 3.5f;
		}

		else if(RandomNumber < 4000)
		{
			FileName += "debris_metal_crate.x";
			Scale = D3DXVECTOR3(0.3f, 0.3f, 0.3f);
			CollisionRadius = 5.5f;
		}

		else if(RandomNumber < 5000)
		{
			FileName += "debris_p01.x";
			CollisionRadius = 2.0f;
		}

		else if(RandomNumber < 6000)
		{
			FileName += "debris_p02.x";
			CollisionRadius = 2.0f;
		}

		else if(RandomNumber < 7000)
		{
			FileName += "debris_rocket_end.x";
			Scale = D3DXVECTOR3(3.0f, 3.0f, 3.0f);
			Rotation = GetAPlanetaryRotation();
			CollisionRadius = 22.0f;
		}

		else if(RandomNumber < 8000)
		{
			FileName += "debris_rocket_mid.x";
			Scale = D3DXVECTOR3(3.0f, 3.0f, 3.0f);
			Rotation = GetAPlanetaryRotation();
			CollisionRadius = 14.5f;
		}

		else if(RandomNumber < 9000)
		{
			FileName += "debris_rocket_top.x";
			Scale = D3DXVECTOR3(3.0f, 3.0f, 3.0f);
			Rotation = GetAPlanetaryRotation();
			CollisionRadius = 12.0f;
		}

		else if(RandomNumber < 10000)
		{
			FileName += "debris_wing.x";
			Scale = D3DXVECTOR3(3.0f, 3.0f, 3.0f);
			Rotation = GetAPlanetaryRotation();
			CollisionRadius = 9.0f;
		}
		else if(RandomNumber < 11000)
		{
			FileName += "oxyTank.x";
			Scale = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
			Rotation = GetAPlanetaryRotation();
			CollisionRadius = 8.0f;
		}
		else if(RandomNumber < 12000)
		{
			FileName += "oxyTankAged.x";
			Scale = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
			Rotation = GetAPlanetaryRotation();
			CollisionRadius = 8.0f;
		}
		else if(RandomNumber < 13000)
		{
			FileName += "oxyTankBottom.x";
			Scale = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
			Rotation = GetAPlanetaryRotation();
			CollisionRadius = 6.0f;
		}
		else if(RandomNumber < 14000)
		{
			FileName += "oxyTankTop.x";
			Scale = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
			Rotation = GetAPlanetaryRotation();
			CollisionRadius = 6.0f;
		}

		//DEBUG
		/*FileName = "Models/oxyTankTop.x";
		Scale = D3DXVECTOR3(1.0f, 1.0f, 1.0f);
		Rotation = GetAPlanetaryRotation();
		CollisionRadius = 6.0f;*/
		//END DEBUG

		TempPosition = GetRandomPosition(radius);

		Debris = new Planet(gd3dDevice, Position + TempPosition, Scale, Rotation);
		Debris->LoadXFile(FileName, NULL);
		Debris->SetAngles(GetRandomAngle());
		
		Debris->MainSphere.Position = Debris->GetPosition();
		Debris->MainSphere.Radius = CollisionRadius;
		Globals->Planets.push_back(Debris);

	}
}

D3DXVECTOR3 CDirectXFramework::GetAPlanetaryRotation( void )
{
	UINT RandomNumber = rand() % 300;
	D3DXVECTOR3 Rotation(0,0,0);

	if(RandomNumber < 100)
		Rotation = D3DXVECTOR3(DegToRad(float(Random->DoubleGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine))),0,0);

	else if(RandomNumber < 200)
		Rotation = D3DXVECTOR3(0, DegToRad(float(Random->DoubleGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine))) ,0);

	else
		Rotation = D3DXVECTOR3(0, 0, DegToRad(float(Random->DoubleGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine))) );

	return Rotation;
}

D3DXVECTOR3 CDirectXFramework::GetRandomPosition( UINT radius )
{
	UINT RandomNumber;
	D3DXVECTOR3 TempPosition(0,0,0);

	RandomNumber = rand()%1000;
	if(RandomNumber >= 500)
		TempPosition.x = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % radius));
	else
		TempPosition.x = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% radius));

	RandomNumber = rand()%1000;
	if(RandomNumber >= 500)
		TempPosition.y = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % radius));
	else
		TempPosition.y = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% radius));

	RandomNumber = rand()%1000;
	if(RandomNumber >= 500)
		TempPosition.z = float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) % radius));
	else
		TempPosition.z = -float((Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine)% radius));

	return TempPosition;
}

D3DXVECTOR3 CDirectXFramework::GetRandomDebrisRotation( void )
{
	UINT RandomNumber = rand() % 300;
	D3DXVECTOR3 Rotation(0,0,0);

	if(RandomNumber < 100)
		Rotation = D3DXVECTOR3(DegToRad(float(Random->DoubleGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine))),0,0);

	else if(RandomNumber < 200)
		Rotation = D3DXVECTOR3(0, DegToRad(float(Random->DoubleGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine))) ,0);

	else
		Rotation = D3DXVECTOR3(0, 0, DegToRad(float(Random->DoubleGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine) * Random->IntGenerator(Random->MersEngine))) );

	Rotation *= 3;

	return Rotation;
}

D3DXVECTOR3 CDirectXFramework::GetRandomAngle( void )
{
	//UINT RandomNumber = rand() % 300;
	D3DXVECTOR3 Rotation(0,0,0);

	Rotation.x = DegToRad(float(rand()%360));
	Rotation.y = DegToRad(float(rand()%360));
	Rotation.z = DegToRad(float(rand()%360));

	return Rotation;
}